package com.slunk.dodgetrain;

import com.slunk.physics.characters.AI_Person;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import java.util.Timer;
import java.util.TimerTask;

public class CrowdManager {
	Array<AI_Person> crowds;
	private static int MAX_PEOPLE;
	private Timer timer;
	private World world;
	private float screenWidth;
	private float screenHeight;
	private long MIN_SCHEDULE = 1000;
	private long MAX_SCHEDULE = 2000;
	private long schedule;
	
	public boolean isReadyForBirth = false;
	
	public CrowdManager(World world, float screenWidth, float screenHeight, int maxPeople) {
		this.world = world;
		this.screenWidth = screenWidth;
		this.screenHeight = screenHeight;
		this.crowds = new Array<AI_Person>();
		this.MAX_PEOPLE = 200;
		
		this.schedule = (long)MathUtils.random(this.MIN_SCHEDULE,this.MAX_SCHEDULE);
		timer = new Timer();
        timer.schedule(new Person(), this.schedule);
	}
	
	public void increaseBabyOutput() {
		if (MIN_SCHEDULE >= 200 && MAX_SCHEDULE >= 200) {
			this.setMinMaxSchedules(MIN_SCHEDULE - 100, MAX_SCHEDULE - 100);
		}
	}
	
	public void decreaseBabyOutput() {
		if (MIN_SCHEDULE < 1000 && MAX_SCHEDULE < 2000) {
			this.setMinMaxSchedules(MIN_SCHEDULE + 25, MAX_SCHEDULE + 25);
		}
	}
	
	public void drawPeoples(SpriteBatch batch) {
		for (AI_Person person : this.crowds) {
			person.drawSprite(batch);
		}
	}
	
	public void removeAllPeople() {
		Array<AI_Person> copy_crowds = new Array<AI_Person>(this.crowds);
		for (AI_Person person : copy_crowds) {
			this.world.destroyBody(person.getCharacterBody());
			this.removeFromCrowd(person);
		}
	}
	
	public void setMinMaxSchedules(long minSchedule, long maxSchedule) {
		this.MIN_SCHEDULE = minSchedule;
		this.MAX_SCHEDULE = maxSchedule;
	}
	
	public boolean isBodyInCrowds(Body body) {
		for (AI_Person person : crowds) {
			if (person.getCharacterBody() == body) {
				return true;
			}
		}
		return false;
	}
	
	public void updateCrowdMovement() {
		for (AI_Person person : this.crowds) {
			if (person.getCurrentState() != null) {
				person.updateMovement();
			}
		}
	}
	
	public void removeFromCrowd(AI_Person person) {
		if (this.crowds.contains(person, true)) {
			person.dispose();
			this.crowds.removeValue(person, true);
		}
	}
	
	public boolean isReadyForBirth() {
		return this.isReadyForBirth;
	}
	
	public void birthPerson() {
		float randomX = MathUtils.random(0.0f, screenWidth);
		float randomY = MathUtils.random(0.0f, screenHeight);
		AI_Person baby = new AI_Person(this.world, new Vector2(randomX,randomY),3.0f,6.0f);
		baby.setSprite("data/Person.png");

		this.crowds.add(baby);
		
		isReadyForBirth = false;
		
		if (this.crowds.size < MAX_PEOPLE) {
			this.schedule = (long)MathUtils.random(MIN_SCHEDULE,MAX_SCHEDULE);
	    	this.timer.schedule(new Person(), this.schedule);
    	}
	}
	
	public void resetBirthRate() {
		this.MIN_SCHEDULE = 1000;
		this.MAX_SCHEDULE = 2000;
	}
	
	//Timer class extended as Person to randomly birth new people if there are not enough people on the field
	class Person extends TimerTask {
        public void run() {
        	isReadyForBirth = true;
        }
    }
}
